package controllers.managers
{
	import com.google.maps.LatLng;
	import com.google.maps.LatLngBounds;
	import com.google.maps.services.ClientGeocoder;
	import com.google.maps.services.ClientGeocoderOptions;
	import com.google.maps.services.GeocodingEvent;
	import com.google.maps.services.GeocodingResponse;
	
	import controllers.managers.SingletonManager;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	
	import model.GoogleGeoResult;
	import model.registry.ErrorMessage;
	
	import mx.core.UIComponent;
	import mx.logging.ILogger;
	
	import utils.GoogleLocationParser;
	import utils.LogUtil;
	
	/**
	 * 地址查询管理
	 * 1.系统启动的时候  
	 * 2.相关经纬度被缓存，节省带宽
	 */
	public class LocationQueryManager extends EventDispatcher
	{
		public static var NAME : String = "LocationQueryManager";
//		public static var QUERY_GOOGLE_URL : String = "http://maps.google.com/maps/api/geocode/xml?latlng={0}&language=zh-CN&sensor=false";
		public static var QUERY_GOOGLE_URL : String = "http://xxxx32.com";
		public static var TEST_LNG : String = "39.910093,116.403945";
		
		public static var EVENT_UPDATE : String = "EVENT_UPDATE";
		public static var EVENT_UPDATE_ERROR : String = "EVENT_UPDATE_ERROR";
		public static var EVENT_SECURITY_ERROR : String = "EVENT_SECURITY_ERROR";
		
		[Bindable]
		public var formattedAddress:String;
		
		private var xmlLoader : URLLoader = null;
		private var logger:ILogger = null;
		private var queryLocatStr : String = null;
		private var dataStore:DataStoreManager = null;
		
		public function LocationQueryManager()
		{
			logger = LogUtil.getInst().getLogger(this);
			logger.info("初始化"+NAME);
			xmlLoader = new URLLoader();
			xmlLoader.dataFormat = URLLoaderDataFormat.TEXT;
			xmlLoader.addEventListener(Event.COMPLETE, onDataRespHandler);
			xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorHandler);
			xmlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityHandler);
			xmlLoader.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
		}
		
		/**
		 *  查询指定的地址
		 *  格式如下 ："39.910093,116.403945"
		 **/
		public function query(locStr:String):void
		{
			queryLocatStr = locStr;
			dataStore = DataStoreManager(SingletonManager.getServ(DataStoreManager.NAME));
			if ( dataStore.get( locStr ) == null )
			{
				logger.info("查询地址:"+locStr);
				
				//使用新API
				doQueryByAPI();
				
//				QUERY_GOOGLE_URL = QUERY_GOOGLE_URL.replace("{0}", locStr);
//				xmlLoader.load(new URLRequest(QUERY_GOOGLE_URL));
			}
			else
			{
				logger.info("从cache中获取:"+dataStore.get( locStr ));
				formattedAddress = String(dataStore.get(locStr));
				dispatchEvent( new Event(EVENT_UPDATE) );
			}
		}
		
		/**
		 * 查询异常
		 **/		
		private function doQueryByAPI():void
		{
			var list:Array = queryLocatStr.split(",");
			if(list.length >= 2)
			{
				var lat:Number = formatString2Num(list[0]);
				var lng:Number = formatString2Num(list[1]);
				var qLatlng:LatLng = new LatLng(lat, lng);
				var queryLatlngBounds:LatLngBounds = new LatLngBounds(qLatlng, qLatlng);
				var geocoder:ClientGeocoder = new ClientGeocoder(
					new ClientGeocoderOptions({
						viewport: queryLatlngBounds
					}));
				geocoder.reverseGeocode(qLatlng);
				geocoder.addEventListener(GeocodingEvent.GEOCODING_SUCCESS, onQuerySuccessHandler);
				geocoder.addEventListener(GeocodingEvent.GEOCODING_FAILURE, onQueryFailureHandler);
			}
			else
			{
				throw new Error(ErrorMessage.BAD_QUERY_LOCATION_PARAM);
			}
		}
		
		/**
		 * 查询成功
		 **/
		private function onQuerySuccessHandler(evt:GeocodingEvent):void
		{
			if(evt.response != null)
			{
				var resp:GeocodingResponse = evt.response;
				var addressList:Array = resp.placemarks;
				if(addressList != null && addressList.length > 0)
				{
					var addresText:String = addressList[0].address;
					logger.info("查询到结果了...");
					dataStore.set( queryLocatStr, addresText);
					logger.info("你的地址是:"+addresText);
					formattedAddress = addresText;
					dispatchEvent(new Event(LocationQueryManager.EVENT_UPDATE));
				}
			}
		}
		
		/**
		 * 查询失败
		 **/
		private function onQueryFailureHandler(event:GeocodingEvent):void
		{
			dispatchEvent(new Event(LocationQueryManager.EVENT_UPDATE_ERROR));
		}
		
		/**
		 *  将字符转化成数字
		 **/
		private function formatString2Num(str:String):Number
		{
			return (str == null || str == "") ? 0 : Number(str);
		}
		
		/**
		 * 查询到数据后
		 **/
		private function onDataRespHandler(evt:Event):void
		{
			logger.info("查询到结果了...");
			var xmlData:XML = XML(evt.target.data);
			var parser:GoogleLocationParser = new GoogleLocationParser(xmlData);
			if ( parser.getStatus() && parser.getResultList().length > 0 )
			{
				var result:GoogleGeoResult = GoogleGeoResult(parser.getResultList().getItemAt(0));
				dataStore.set( queryLocatStr, result.getFormattedAddress());
				logger.info("你的地址是:"+result.getFormattedAddress());
				formattedAddress = result.getFormattedAddress();
				dispatchEvent(new Event(LocationQueryManager.EVENT_UPDATE));
			}
		}
		
		/**
		 * 安全沙箱异常
		 **/
		private function onSecurityHandler(event:Event):void
		{
			logger.error("安全异常.");
			doQueryByAPI();
			dispatchEvent(new Event(LocationQueryManager.EVENT_SECURITY_ERROR));
		}
		
		/**
		 * 找不到地址的时候
		 **/
		private function onIOErrorHandler(event:IOErrorEvent):void
		{
			logger.error("找不到地址");
			doQueryByAPI();
			dispatchEvent(new Event(LocationQueryManager.EVENT_UPDATE_ERROR));
		}
		
		/**
		 * 进度
		 **/
		private function onProgressHandler(evt:ProgressEvent):void
		{
			logger.info("加载了:"+evt.bytesLoaded + " / " + evt.bytesLoaded );
		}
	}
}